package com.decard.baselibrarydemo.utils;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.BitmapFactory;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;

import com.decard.NDKMethod.BasicOper;
import com.decard.NDKMethod.DCReader;
import com.decard.baselibrarydemo.App;
import com.decard.baselibrarydemo.R;
import com.decard.baselibrarydemo.UsbPermissionReceiver;
import com.decard.baselibrarydemo.model.DeviceModel;
import com.decard.baselibrarydemo.model.IdCardBean;
import com.decard.baselibrarydemo.model.QRCodeCallback;
import com.decard.baselibrarydemo.model.ReadCardUtilsCallback;
import com.decard.baselibrarydemo.model.SocialSecurityCardBean;
import com.decard.driver.utils.HexDump;
import com.decard.entitys.IDCard;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
 * @Description
 * @Author WuJianFeng
 * @Date 2023/12/26 10:41
 */

public class ReadCardUtilsPad implements LifecycleEventObserver,UsbPermissionCallback {

    private UsbPermissionReceiver usbPermissionActionReceiver;

    private volatile static ReadCardUtilsPad instance;

    public static ReadCardUtilsPad getInstance(Context context) {
        if (instance == null) {
            synchronized (ReadCardUtilsPad.class) {
                if (instance == null) {
                    instance = new ReadCardUtilsPad(context);
                }

            }
        }
        return instance;
    }


    private Context context;

    private ReadCardUtilsPad(Context context) {
        this.context = context;
    }


    /**
     * 获得 usb 权限
     */
    private void tryGetUsbPermission() {
        UsbManager mUsbManager = (UsbManager)context.getSystemService(Context.USB_SERVICE);
        usbPermissionActionReceiver = new UsbPermissionReceiver(this);
        IntentFilter filter = new IntentFilter(UsbPermissionReceiver.ACTION_USB_PERMISSION);
        context.registerReceiver(usbPermissionActionReceiver, filter);

        PendingIntent mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(UsbPermissionReceiver.ACTION_USB_PERMISSION), 0);

        //here do emulation to ask all connected usb device for permission
        for (final UsbDevice usbDevice : mUsbManager.getDeviceList().values()) {
            if (usbDevice.getVendorId() == 9595 && usbDevice.getProductId() == 12305 ||
                    usbDevice.getVendorId() == 9595 && usbDevice.getProductId() == 12306 ||
                    usbDevice.getVendorId() == 9595 && usbDevice.getProductId() == 12304 ||
                    usbDevice.getVendorId() == 9595 && usbDevice.getProductId() == 40961 ||
                    usbDevice.getVendorId() == 9595 && usbDevice.getProductId() == 40963 ||
                    usbDevice.getVendorId() == 1137 && usbDevice.getProductId() == 28674 ||
                    usbDevice.getVendorId() == 1137 && usbDevice.getProductId() == 28675 ||
                    usbDevice.getVendorId() == 1137 && usbDevice.getProductId() == 41234 ||
                    usbDevice.getVendorId() == 1137 && usbDevice.getProductId() == 41299 ||
                    usbDevice.getVendorId() == 1137 && usbDevice.getProductId() == 41267 ||
                    usbDevice.getVendorId() == 9595 && usbDevice.getProductId() == 12337 ||
                    usbDevice.getVendorId() == 1137 && usbDevice.getProductId() == 41253) {
                if (mUsbManager.hasPermission(usbDevice)) {
                    //已经拥有权限
                    connect();

                } else {
                    mUsbManager.requestPermission(usbDevice, mPermissionIntent);
                }
            }
        }

    }

    /**
     * 连接
     */
    public void connect() {
        int portSate = BasicOper.dc_open("AUSB", context, "", 0);
        DeviceModel.setPort(portSate);
        if (portSate >= 0) {
            BasicOper.CreateAndroidContext(context);
            BasicOper.dc_beep(5);
            //设备已连接
            ((Activity)context).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(App.app, App.app.getString(R.string.openSuccessed), Toast.LENGTH_SHORT).show();

                }
            });

        } else {
            ((Activity)context).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(App.app, "串口打开失败，请退出软件重启", Toast.LENGTH_SHORT).show();

                }
            });

        }
        Log.d("TagT", "portSate:" + portSate);
    }

    public void disconnect() {

        int close_status = BasicOper.dc_exit();
        DeviceModel.setPort(-1);
        if (close_status >= 0) {
            Toast.makeText(App.app, "The port is close successfully", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(App.app, "Port has closed", Toast.LENGTH_SHORT).show();
        }
    }

    private boolean canReadIdCard = true;
    public void readIdCard(ReadCardUtilsCallback readCardUtilsCallback) {
        canReadIdCard = true;
        new Thread(new Runnable() {
            @Override
            public void run() {

                while (canReadIdCard) {
                    try {
                        //身份证
                        IDCard idCard = BasicOper.dc_SamAReadCardInfo(1);
                        if (idCard != null) {
                            Log.d("__readIdCard-1","1");
                            canReadIdCard = false;
                            IdCardBean idCardBean = new IdCardBean();
                            idCardBean.setName(idCard.getName().replace(" ","").trim());
                            idCardBean.setGender(idCard.getSex().trim());
                            idCardBean.setGroup(idCard.getNation().trim());
                            idCardBean.setBorn(idCard.getBirthday().trim());
                            idCardBean.setAddress(idCard.getAddress().trim());
                            idCardBean.setIdNumber(idCard.getId().trim());
                            idCardBean.setIssueAuthority(idCard.getOffice().trim());
                            idCardBean.setStartDate(idCard.getStartTime().trim());
                            idCardBean.setEndDate(idCard.getEndTime().trim());
                            idCardBean.setPhotoBitmap(BitmapFactory.decodeByteArray(idCard.getPhotoData(), 0, idCard.getPhotoData().length));
                            readCardUtilsCallback.idCardData(idCardBean);

                        }

                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        Log.d("__readIdCard-3",e.getMessage());
                        readCardUtilsCallback.errMsg(e.getMessage());
                        e.printStackTrace();
                    }
                }
            }
        }).start();

    }

    public void readIdCardStop(){
        canReadIdCard = false;
    }

    public void readSocial(ReadCardUtilsCallback readCardUtilsCallback){
        byte[] bytes = new byte[1024];
        long ret = DCReader.iReadSIEF06(bytes);

        try {
            String result = new String(bytes,"gbk").trim();
            Log.d("__social","接口结果："+ret+"    " +result);
            if (ret == 0){
                String[] splitArr = result.split("\\|");
                Log.d("__social-e","length = " +splitArr.length + "str = "+Arrays.toString(splitArr));
                SocialSecurityCardBean socialSecurityCardBean = new SocialSecurityCardBean();
                socialSecurityCardBean.setCardNum(splitArr[0].trim());
                socialSecurityCardBean.setName(splitArr[1].trim());
                socialSecurityCardBean.setBorn(splitArr[5].trim());
                socialSecurityCardBean.setGender(splitArr[2].trim().equals("1")? "男":"女");
                readCardUtilsCallback.socialSecurityCardData(socialSecurityCardBean);
            }else {
                if (ret == -2){
                    readCardUtilsCallback.nullCard();
                }else {
                    readCardUtilsCallback.errMsg(result);
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    private boolean canScanQRCode = false;
    public void scanQRCode(QRCodeCallback qrCodeCallback) {
        canScanQRCode = true;

        //开启二维码扫描
        String start_scan_2D = BasicOper.dc_Scan2DBarcodeStart(0x00);
        Log.d("__startScan", "run:二维码"+start_scan_2D);
        if (start_scan_2D.split("\\|")[0].equals("0000")) {
            new Thread(new Runnable() {
                @Override
                public void run() {

                    while (canScanQRCode){
                        try {
                            String scan_2D_info = BasicOper.dc_Scan2DBarcodeGetData();
                            //获取二维码扫描结果
                            Log.d("__startScan", "BasicOper.dc_Scan2DBarcodeGetData：" + scan_2D_info);
                            if (scan_2D_info.split("\\|")[0].equals("0000")) {
                                canScanQRCode = false;
                                try {
                                    String data = new String(HexDump.hexStringToByteArray(scan_2D_info.split("\\|")[1]),"Gbk").trim();
                                    qrCodeCallback.result(data);
                                } catch (UnsupportedEncodingException e) {
                                    e.printStackTrace();
                                }
                            }
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();

        }
    }

    public void scanQRCodeStop(){
        canScanQRCode = false;
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {

        switch (event) {

            case ON_CREATE:{
                tryGetUsbPermission();
                break;
            }
            case ON_DESTROY: {
                disconnect();
                DeviceModel.setPort(-1);
                BasicOper.dc_exit();
                context.unregisterReceiver(usbPermissionActionReceiver);

                context = null;
                instance = null;
                break;
            }
            default:
                break;
        }
    }

    @Override
    public void result() {
        connect();
    }
}
